<?php
	
//------------------------------------------------------------------
// File: dataAccess.php
// Author: Bryan Frost
// Date Created: 2010-03-25
//
// Database Management
//------------------------------------------------------------------
ini_set("display_standard_errors","0");
ini_set("display_errors","1");

// TODO: Convert to object oriented db connection.


// Define database connection constants
define('DB_HOST', localhost);
define('DB_USER', 'phillipv_user1');
define('DB_PASSWORD', 'pas');
define('DB_NAME', 'phillipv_AVA');

define('MAX_TOURNAMENTS_PER_SEASON','5');

// Use this micro-class to compute current season once
class CurrentDate
{
    private static $_currentDate;

    private static function LoadCurrentDate()
    {
        $query = "SELECT * FROM Events ORDER BY StartDate DESC LIMIT 0,1";

        $result = GetQueryResult($query);

        while($row = mysqli_fetch_array($result))
        {
            return $row['StartDate'];
        }

        return false;
    }

    public static function GetCurrentSeason()
    {
        if ( CurrentDate::$_currentDate === null )
        {
            CurrentDate::$_currentDate = strtotime(CurrentDate::LoadCurrentDate());
        }

        return intval(date('Y',CurrentDate::$_currentDate));
    }
}

class CurrentSeasonPointsCalculator
{
    // Current player stored values.  Will be re-set when a new player's data is requested
    private static $currentPlayerEventsArray = array();
    private static $currentPlayerID = false;
    private static $currentPlayerPointsTotal = 0;
    private static $currentPlayerEventsPlayed = 0;
    private static $currentPlayerRating = 0;

    // Global stored values.  Will only be queried once.
    private static $oneTimeQueryDone = false;

    // We will use n events to calculate current season points,
    // where n = max(eventsInCurrentSeason,eventsInPreviousSeason)
    private static $numEventsInCurrentSeason = 0;
    private static $numEventsInPreviousSeason = 0;
    private static $numEventsToUse = 0;
    private static $eventsInPreviousSeason = array();
    private static $eventsInCurrentSeason = array();
    private static $eligibleEventIDs = array();

    private static function LoadCurrentSeason($playerID)
    {
        if ( $playerID == CurrentSeasonPointsCalculator::$currentPlayerID )
            return;

        CurrentSeasonPointsCalculator::$currentPlayerID = $playerID;
        CurrentSeasonPointsCalculator::$currentPlayerEventsArray = array();
        CurrentSeasonPointsCalculator::$currentPlayerPointsTotal = 0;
        CurrentSeasonPointsCalculator::$currentPlayerEventsPlayed = 0;
        CurrentSeasonPointsCalculator::$currentPlayerRating = 0;

        // Get all events from the current year and last year
        $currentSeason = CurrentDate::GetCurrentSeason();

        $query = "SELECT PlayerID, P.GenderID, TOUR.StartDate, E.StartDate, Result, NumberOfTeams, DivisionID, ".
        "E.GenderID, EventID, Division, TeamID, Year(E.StartDate) AS Year ".
        "FROM Players P ".
        "INNER JOIN Teams T USING (PlayerID) ".
        "INNER JOIN Results R USING (TeamID) ".
        "INNER JOIN Events E USING (EventID) ".
        "INNER JOIN Divisions D USING (DivisionID) ".
        "INNER JOIN Tournaments TOUR USING (TournamentID) ".
        "WHERE P.PlayerID = $playerID ".
        "AND P.GenderID = E.GenderID ".
        "ORDER BY E.StartDate DESC, E.GenderID, E.DivisionID";

        $result = GetQueryResult($query);

        $genderId = 0;

        while($row = mysqli_fetch_array($result))
        {
            // Calculate points earned
            $results = $row['Result'];
            $numberOfTeams = $row['NumberOfTeams'];
            $divisionId = $row['DivisionID'];
            $genderId = $row['GenderID'];
            $points = CalculatePoints($genderId, $divisionId, $numberOfTeams, $results);

            $finish = $row['Result'];
            $startYear = $row['Year'];
            $rating = CalculateRatingEarned($genderId, $divisionId, $numberOfTeams, $finish);
            // Use calendar date for ratings
            $ratingYearDifference = intval(date('Y')) - $startYear;
            $ratingYearAdjustment = $ratingYearDifference - ($ratingYearDifference > 0 ? 1 : 0);
            $rating += $ratingYearAdjustment;

            if ( CurrentSeasonPointsCalculator::$currentPlayerRating == 0 ||
                    $rating < CurrentSeasonPointsCalculator::$currentPlayerRating )
                CurrentSeasonPointsCalculator::$currentPlayerRating = $rating;

            // Count towards current or previous year event count
            $eventID = $row['EventID'];

            CurrentSeasonPointsCalculator::$currentPlayerEventsArray[] =
                array('points' => $points, 'eventID' => $eventID);
        }

        if ( CurrentSeasonPointsCalculator::$oneTimeQueryDone == false )
        {
            CurrentSeasonPointsCalculator::$oneTimeQueryDone = true;

            $query =    "SELECT EventID, StartDate, GenderID, DivisionID FROM Events
                          WHERE Year(StartDate)=$currentSeason AND GenderID=$genderId
                          ORDER BY StartDate DESC";

            $result = GetQueryResult($query);

            while ($row = mysqli_fetch_array($result))
            {
                CurrentSeasonPointsCalculator::$numEventsInCurrentSeason++;
                CurrentSeasonPointsCalculator::$eventsInCurrentSeason[] = $row['EventID'];
            }

            $query =    "SELECT EventID, StartDate, GenderID, DivisionID FROM Events
                        WHERE Year(StartDate)=($currentSeason - 1) AND GenderID=$genderId
                        ORDER BY StartDate DESC";

            $result = GetQueryResult($query);

            while ($row = mysqli_fetch_array($result))
            {
                CurrentSeasonPointsCalculator::$numEventsInPreviousSeason++;
                CurrentSeasonPointsCalculator::$eventsInPreviousSeason[] = $row['EventID'];
            }

            CurrentSeasonPointsCalculator::$numEventsToUse =
                CurrentSeasonPointsCalculator::$numEventsInCurrentSeason >=
                    CurrentSeasonPointsCalculator::$numEventsInPreviousSeason ?
                        CurrentSeasonPointsCalculator::$numEventsInCurrentSeason :
                        CurrentSeasonPointsCalculator::$numEventsInPreviousSeason;

            if ( CurrentSeasonPointsCalculator::$numEventsToUse > MAX_TOURNAMENTS_PER_SEASON )
                CurrentSeasonPointsCalculator::$numEventsToUse = MAX_TOURNAMENTS_PER_SEASON;

            for ( $idx = 0; $idx < CurrentSeasonPointsCalculator::$numEventsToUse &&
                        $idx < CurrentSeasonPointsCalculator::$numEventsInCurrentSeason; $idx++ )
            {
                CurrentSeasonPointsCalculator::$eligibleEventIDs[$idx] =
                    CurrentSeasonPointsCalculator::$eventsInCurrentSeason[$idx];
            }

            for ( ; $idx < CurrentSeasonPointsCalculator::$numEventsToUse; $idx++ )
            {
                CurrentSeasonPointsCalculator::$eligibleEventIDs[$idx] =
                    CurrentSeasonPointsCalculator::$eventsInPreviousSeason[$idx -
                    CurrentSeasonPointsCalculator::$numEventsInCurrentSeason];
            }
        }

        for ( $i = 0; $i < CurrentSeasonPointsCalculator::$numEventsToUse; $i++ )
        {
            $eligible = false;
            for($j = 0; $j < CurrentSeasonPointsCalculator::$numEventsToUse; $j++ )
            {
                if ( CurrentSeasonPointsCalculator::$currentPlayerEventsArray[$i]['eventID'] ==
                        CurrentSeasonPointsCalculator::$eligibleEventIDs[$j] )
                {
                    $eligible = true;
                    break;
                }
            }

            if ( $eligible )
            {
                CurrentSeasonPointsCalculator::$currentPlayerPointsTotal +=
                    CurrentSeasonPointsCalculator::$currentPlayerEventsArray[$i]['points'];

                CurrentSeasonPointsCalculator::$currentPlayerEventsPlayed++;
            }
        }
    }

    public static function GetCurrentSeasonPoints($playerID)
    {
        CurrentSeasonPointsCalculator::LoadCurrentSeason($playerID);

        return CurrentSeasonPointsCalculator::$currentPlayerPointsTotal;
    }

    public static function GetCurrentSeasonPlayed($playerID)
    {
        CurrentSeasonPointsCalculator::LoadCurrentSeason($playerID);

        return CurrentSeasonPointsCalculator::$currentPlayerEventsPlayed;
    }

    public static function GetCurrentSeasonRating($playerID)
    {
        CurrentSeasonPointsCalculator::LoadCurrentSeason($playerID);

        return CurrentSeasonPointsCalculator::$currentPlayerRating;
    }

    public static function SavePlayerCurrentSeasonData($playerID)
    {
        CurrentSeasonPointsCalculator::LoadCurrentSeason($playerID);

        if ( CurrentSeasonPointsCalculator::$currentPlayerRating == 0 )
            CurrentSeasonPointsCalculator::$currentPlayerRating = 4;

        $query = "UPDATE Players SET
                    CurrentPlayed=".CurrentSeasonPointsCalculator::$currentPlayerEventsPlayed.",
                    CurrentPoints=".CurrentSeasonPointsCalculator::$currentPlayerPointsTotal.",
                    CurrentUnadjustedRating=".CurrentSeasonPointsCalculator::$currentPlayerRating.",
                    CurrentUnadjustedRatingDate=CURDATE()"."
                WHERE PlayerID=".$playerID;

        GetQueryResult($query);
    }
}

function GetConnection()
{
	$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
		or die('Error connecting to MySQL server.');
	
	return $dbc;
}



// Generic query function.
function GetQueryResult($query)
{
	$dbc = GetConnection();
	$result = mysqli_query($dbc,$query);
//		or die("Error querying MySQL server.");

    if (!$result) {
        printf("Error: %s\n", mysqli_error($dbc));
        exit();
    }
	mysqli_close($dbc);
	
	return $result;
}

?>